package com.gateway.service;

import com.gateway.entity.GatewayEntity;
import com.gateway.dao.GatewayMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 网关配置实现类
 * @Author: mis_wu
 * @Date: 2022/4/28
 **/
@Service
@Transactional(rollbackFor = Exception.class)
public class GatewayService implements ApplicationEventPublisherAware {

    /**
     * 路由类型
     */
    private static final String ROUTE_TYPE = "0";

    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    @Resource
    private GatewayMapper gatewayMapper;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

    public String loadAllRoutes(){
        List<GatewayEntity> allGatewayConfig = gatewayMapper.getAllGatewayConfig();
        for (GatewayEntity allConfig : allGatewayConfig) {
            loadRoute(allConfig);
        }
        return "all gateway config load success";
    }

    public String loadRoute(GatewayEntity gatewayEntity){
        RouteDefinition definition = new RouteDefinition();
        Map<String, String> predicateParams = new HashMap<>(8);
        PredicateDefinition predicate = new PredicateDefinition();
        Map<String, String> filterParams = new HashMap<>(8);
        FilterDefinition filterDefinition = new FilterDefinition();
        URI uri = null;
        //ROUTE_TYPE写在equals()前面,防止空指针
        if (ROUTE_TYPE.equals(gatewayEntity.getRouteType())){
            //如果为0,从注册中心获取服务地址
            uri = UriComponentsBuilder.fromUriString("lb://"+gatewayEntity.getRouteUrl()+"/").build().toUri();
        }else {
            uri = UriComponentsBuilder.fromHttpUrl(gatewayEntity.getRouteUrl()).build().toUri();
        }
        //定义路由唯一id
        definition.setId(gatewayEntity.getRouteId());
        predicate.setName("Path");

        //定义路由转发
        predicateParams.put("pattern",gatewayEntity.getRoutePattern());
        predicate.setArgs(predicateParams);

        //定义过滤规则,名称固定,路径去前缀
        filterDefinition.setName("StripPrefix");
        filterParams.put("_genkey_0",gatewayEntity.getRouteFilters());
        filterDefinition.setArgs(filterParams);
        definition.setPredicates(Arrays.asList(predicate));
        definition.setFilters(Arrays.asList(filterDefinition));
        definition.setUri(uri);
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return "gateway success";
    }
}
